package com.dhemery.mack.actions.tests;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.junit.Before;
import org.junit.Test;
import com.dhemery.mack.actions.ShowProjectExplorerAction;
import com.dhemery.mack.adapters.ImageDescriptorSource;
import com.dhemery.mack.adapters.tests.FakeConstantImageDescriptorSource;
import com.dhemery.mack.adapters.tests.FakeImageDescriptor;
import com.dhemery.mack.gui.ProjectExplorer;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

public class ShowProjectExplorerActionTests {
	private ImageDescriptorSource imageDescriptorSource;
	private IWorkbenchWindow window;
	private IWorkbenchPage page;
	private Event event;
	private IViewPart view;
	private IPartService partService;

	@Before
	public void setup() {
		ImageDescriptor fakeImageDescriptor = new FakeImageDescriptor("fake");
		imageDescriptorSource = new FakeConstantImageDescriptorSource(fakeImageDescriptor);
		window = mock(IWorkbenchWindow.class);
		partService = mock(IPartService.class);
		page = mock(IWorkbenchPage.class);
		view = mock(ProjectExplorer.class);
		event = mock(Event.class);

		stub(window.getActivePage()).toReturn(page);
		stub(window.getPartService()).toReturn(partService);
	}

	@Test
	public void startsUnChecked() {
		ShowProjectExplorerAction action = new ShowProjectExplorerAction(window, imageDescriptorSource);
		
		assertFalse(action.isChecked());
	}

	@Test
	public void listensForWindowPartChanges() {
		ShowProjectExplorerAction action = new ShowProjectExplorerAction(window, imageDescriptorSource);
		
		verify(partService).addPartListener(same(action));
	}

	@Test
	public void setsCheckedTrueWhenProjectExplorerOpens() {
		ShowProjectExplorerAction action = new ShowProjectExplorerAction(window, imageDescriptorSource);
		
		action.partOpened(view);

		assertTrue(action.isChecked());
	}

	@Test
	public void setsCheckedFalseWhenProjectExplorerCloses() {
		ShowProjectExplorerAction action = new ShowProjectExplorerAction(window, imageDescriptorSource);
		action.setChecked(false);

		action.partClosed(view);

		assertFalse(action.isChecked());
	}

	@Test
	public void showsProjectExplorerIfButtonChecked() throws PartInitException {
		Button button = mock(Button.class);

		event.widget = button;
		stub(button.getSelection()).toReturn(true);

		ShowProjectExplorerAction action = new ShowProjectExplorerAction(window, imageDescriptorSource);
		action.runWithEvent(event);

		verify(page).showView(ProjectExplorer.ID);
	}

	@Test
	public void hidesProjectExplorerIfButtonNotChecked() {
		Button button = mock(Button.class);

		stub(page.findView(anyString())).toReturn(view);
		event.widget = button;
		stub(button.getSelection()).toReturn(false);

		ShowProjectExplorerAction action = new ShowProjectExplorerAction(window, imageDescriptorSource);
		action.runWithEvent(event);

		verify(page).hideView(same(view));
	}

	@Test
	public void showsProjectExplorerIfMenuChecked() throws PartInitException {
		MenuItem menuItem = mock(MenuItem.class);

		event.widget = menuItem;
		stub(menuItem.getSelection()).toReturn(true);

		ShowProjectExplorerAction action = new ShowProjectExplorerAction(window, imageDescriptorSource);
		action.runWithEvent(event);

		verify(page).showView(ProjectExplorer.ID);
	}

	@Test
	public void showsProjectExplorerIfMenuNotChecked() {
		MenuItem menuItem = mock(MenuItem.class);

		stub(page.findView(anyString())).toReturn(view);
		event.widget = menuItem;
		stub(menuItem.getSelection()).toReturn(false);

		ShowProjectExplorerAction action = new ShowProjectExplorerAction(window, imageDescriptorSource);
		action.runWithEvent(event);

		verify(page).hideView(same(view));
	}
}
